Skip to content

Go: Add Herb Go FFI Bindings#830

Closed
omarluq wants to merge 2 commits into
marcoroth:mainfrom
omarluq:go-bindings
Closed

Go: Add Herb Go FFI Bindings#830
omarluq wants to merge 2 commits into
marcoroth:mainfrom
omarluq:go-bindings

Conversation

@omarluq

@omarluq omarluq commented Nov 10, 2025

Copy link
Copy Markdown

This PR adds Go bindings for Herb using c-for-go (FFI), allowing Go
applications to parse and analyze ERB templates with the same implementation
as the native C, Ruby C-Extension, C++ Emscripten WASM, Java JNI, Rust FFI,
and the C++ Node.js NAPI bindings.

Building the Go bindings requires Go 1.20+, a C compiler, and c-for-go:

  cd go
  make build

Usage:

  package main

  import (
      "fmt"
      "github.com/marcoroth/herb"
  )

  func main() {
      template := "<h1><%= title %></h1>"

      // Lex
      tokens := herb.Lex(template)

      // Parse
      ast := herb.Parse(template, nil)

      // Extract Ruby
      ruby := herb.Extract(template, 0)
  }

The Go bindings use a minimal wrapper header approach (similar to Java's JNI
bindings) to avoid exposing prism dependencies while linking against both
libherb.a and libprism.a

  This PR adds Go bindings for Herb using `c-for-go` (FFI), allowing Go
  applications to parse and analyze ERB templates with the same implementation
  as the native C, Ruby C-Extension, C++ Emscripten WASM, Java JNI, Rust FFI,
  and the C++ Node.js NAPI bindings.

  Building the Go bindings requires Go 1.20+, a C compiler, and c-for-go:

  ```bash
    cd go
    make build
  ```

  Usage:

  ```go
    package main

    import (
        "fmt"
        "github.com/marcoroth/herb"
    )

    func main() {
        template := "<h1><%= title %></h1>"

        // Lex
        tokens := herb.Lex(template)

        // Parse
        ast := herb.Parse(template, nil)

        // Extract Ruby
        ruby := herb.Extract(template, 0)
    }
  ```
  The Go bindings use a minimal wrapper header approach (similar to Java's JNI
  bindings) to avoid exposing prism dependencies while linking against both
  `libherb.a` and `libprism.a`
@github-actions github-actions Bot added the c label Nov 10, 2025
  Add `InspectTokens()` function to provide formatted token
  output similar to
  Rust/Java bindings:

  - Extend herb_go.h with token structures (position_T,
  range_T, location_T, token_T)
  - Add array and token helper functions (hb_array_size,
  hb_array_get, token_type_to_string)
  - Implement `token_helpers.go` with `InspectTokens()`
  user-facing API
@omarluq

omarluq commented Nov 11, 2025

Copy link
Copy Markdown
Author

Will reopen later after multi backend PR

@omarluq omarluq closed this Nov 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant